﻿//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Mapping Application Block
//===============================================================================

using System;
using System.Configuration;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using EntLibContrib.Mapping.Instrumentation;

namespace EntLibContrib.Mapping
{
	/// <summary>
	/// Contains factory methods for creating Mapper objects.
	/// </summary>
	public static class MapperFactory
	{
		#region Static Fields
		private static MapperProviderFactory factory = new MapperProviderFactory(ConfigurationSourceFactory.Create());
		private static object lockObject = new object();
		#endregion

		#region Public Static Methods
		/// <summary>
		/// Method for invoking a specified Mapper object.  Reads settings
		/// from the ConnectionSettings.config file.
		/// </summary>
		/// <param name="mapperName">Name of the mapper.</param>
		/// <returns>IMapper instance</returns>
		/// <example>
		/// <code>
		///		IMapper customerMapper = MapperFactory.CreateMapper("CustomerMapper");
		///	</code>
		/// </example>
		/// <exception cref="ArgumentNullException">mapper name is null</exception>
		/// <exception cref="ArgumentException">mapper name is empty</exception>
		/// <exception cref="System.Configuration.ConfigurationException">
		/// 	<para><paramref name="instanceName"/> is not defined in configuration.</para>
		/// 	<para>- or -</para>
		/// 	<para>An error exists in the configuration.</para>
		/// 	<para>- or -</para>
		/// 	<para>An error occured while reading the configuration.</para>
		/// </exception>
		/// <exception cref="System.Reflection.TargetInvocationException">The constructor being called throws an exception.</exception>
		public static IMapper CreateMapper(string mapperName)
		{
			try
			{
				lock (lockObject)
				{
					return factory.Create(mapperName);
				}
			}
      catch (ConfigurationErrorsException configurationException)
      {
				TryLogConfigurationError(configurationException, mapperName);
        throw;
      }
		}
		#endregion

		#region Private Static Methods
		[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		private static void TryLogConfigurationError(ConfigurationErrorsException configurationException, string instanceName)
    {
      try
      {
        DefaultMapperEventLogger eventLogger = EnterpriseLibraryFactory.BuildUp<DefaultMapperEventLogger>();
        if (eventLogger != null)
					eventLogger.LogConfigurationError(instanceName, configurationException);
      }
      catch { }
		}
		#endregion
	}
}
